<?
/**
 * Copyright 2007 Melange.
 *
 * This file is part of PHP-MVC.
 *
 * PHP-MVC is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * PHP-MVC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PHP-MVC; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @category    Melange
 * @package     php-mvc
 * @subpackage  view
 * @copyright   Copyright (c) 2007 Jeroen Simons. All rights reserved
 * @author      Jeroen Simons <jeroen@melange.nl>
 * @link        http://www.melange.nl/
 *
 */

/**
 * ActionMessages
 *
 * @category   Melange
 * @package    php-mvc
 * @subpackage action
 * @copyright  Copyright (c) 2007 Jeroen Simons. All rights reserved
 * @license    http://www.gnu.org/licenses/licenses.html#GPL    The GNU General Public License
 */
class ActionMessages {


    // ----------------------------------------------------- Instance Variables


    /**
     * <p>Have the messages been retrieved from this object?</p>
     *
     * <p>The controller uses this property to determine if session-scoped
     * messages can be removed.</p>
     */
    protected $accessed = false;


    /**
     * <p>The accumulated set of <code>ActionMessage</code> objects
     * (represented as an ArrayList) for each property, keyed by property
     * name.</p>
     */
    protected $messages = array();


    // ----------------------------------------------------------- Constructors


    /**
     * <p>Create an <code>ActionMessages</code> object initialized with the
     * given messages.</p>
     *
     * @param messages The messages to be initially added to this object. This
     *                 parameter can be <code>null</code>.
     */
    public function __construct($messages=null) {
        $this->addMessages($messages);
    }


    // --------------------------------------------------------- Public Methods


    /**
     * <p>Adds the messages from the given <code>ActionMessages</code> object
     * to this set of messages. The messages are added in the order they are
     * returned from the <code>properties</code> method. If a message's
     * property is already in the current <code>ActionMessages</code> object,
     * it is added to the end of the list for that property. If a message's
     * property is not in the current list it is added to the end of the
     * properties.</p>
     *
     * @param actionMessages The <code>ActionMessages</code> object to be
     *                       added. This parameter can be <code>null</code>.
     */
    public function addMessages($actionMessages) {

        if (is_null($actionMessages)) {
            return;
        }

        // loop over properties
        while(list($property, $actionMessages) = each($actionMessages)) {

            // loop over messages for each property
            foreach($actionMessages as $actionMessage) {
                $this->add($property, $actionMessage);
            }
        }
    }


    /**
     * <p>Add a message to the set of messages for the specified property. An
     * order of the property/key is maintained based on the initial addition
     * of the property/key.</p>
     *
     * @param property Property name (or ActionMessages.GLOBAL_MESSAGE)
     * @param message  The message to be added
     */
    public function add($property, ActionMessage $message) {
        $this->messages[$property][] = $message;
    }


    /**
     * <p>Clear all messages recorded by this object.</p>
     */
    public function clear() {
        $this->messages = array();
    }


    /**
     * <p>Return <code>true</code> if there are no messages recorded in this
     * collection, or <code>false</code> otherwise.</p>
     *
     * @return <code>true</code> if there are no messages recorded in this
     *         collection; <code>false</code> otherwise.
     */
    public function isEmpty() {
        return empty($this->messages);
    }


    /**
     * <p>Return the set of all recorded messages, without distinction by
     * which property the messages are associated with. If there are no
     * messages recorded, an empty enumeration is returned.</p>
     *
     * @return An iterator over the messages for all properties.
     */
    public function get($property=null) {

        $this->accessed = true;

        if (count($this->messages) == 0) {
            return array();
        }

        if(!is_null($property)) {
            if(array_key_exists($property, $this->messages))
                return $this->messages[$property];
            return null;
        }

        return $this->messages;
    }


    /**
     * <p>Returns <code>true</code> if the <code>get()</code> or
     * <code>get(String)</code> methods are called.</p>
     *
     * @return <code>true</code> if the messages have been accessed one or
     *         more times.
     */
    public function isAccessed() {
        return $this->accessed;
    }


    public function __toString() {
        $sb = "";
        $sb .= "[ActionMessages]";
        return $sb;
    }

}

?>